package org.easyspring.core;

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;

/**
 * 模拟spring加载XML配置文件
 */
public class BeanFactory {
    private static Map<String,Object> beanMap = new HashMap<>();

    public static void main(String[] args) {
        init("role.xml");
    }
    /**
     * bean工厂的初始化
     * @param xml xml配置文件
     */
    public static void init(String xml){
        try {
            SAXReader reader = new SAXReader();
            ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
            //从class目录下获取指定的xml文件
            InputStream inputStream = classLoader.getResourceAsStream(xml);
            Document document = reader.read(inputStream);
            Element root = document.getRootElement();
            Element foo;
            //遍历bean
            for (Iterator i = root.elementIterator("bean");i.hasNext();
                 ) {
                foo =(Element) i.next();
                //获取bean的属性id和class
                Attribute id = foo.attribute("id");
                Attribute cls = foo.attribute("class");
                //利用java反射机制，通过class的名称获取class对象
                Class<?> bean = Class.forName(cls.getText());
                //获取对应class的信息
                BeanInfo info = Introspector.getBeanInfo(bean);
                //获取其属性描述
                PropertyDescriptor[] pd = info.getPropertyDescriptors();
                //设置值的方法
                Method mSet = null;
                //创建一个对象
                Object obj = bean.newInstance();
                for(Iterator ite = foo.elementIterator("property");ite.hasNext();){
                    Element foo2 = (Element) ite.next();
                    Attribute name = foo2.attribute("name");
                    String  value = null;
                    //获取该property的子元素value的值
                    for(Iterator ite1 = foo2.elementIterator("value");ite1.hasNext();){
                        Element node = (Element) ite1.next();
                        value = node.getText();
                        break;
                    }
                    for (int j = 0; j < pd.length; j++) {
                        if(pd[j].getName().equalsIgnoreCase(name.getText())){
                            mSet = pd[j].getWriteMethod();
                            //利用反射调用对象的某个set方法,并将值进去
                            mSet.invoke(obj,value);
                        }
                    }
                }
                //将对象放入beanMap中，其中key为id的值,value为对象
                beanMap.put(id.getText(),obj);
            }
            System.out.println(beanMap);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
